package status

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"shimmer/neusoft_club_backend/controllers/cons"
	"shimmer/neusoft_club_backend/dao/domain"
	"shimmer/neusoft_club_backend/middlewares/auth_middleware"
	"shimmer/neusoft_club_backend/services"
	"shimmer/neusoft_club_backend/services/club_service"
	"shimmer/neusoft_club_backend/services/errs"
	"shimmer/neusoft_club_backend/services/form_service"
)

// @Summary 获取表单的流程结构
// @Description
// @Tags 表单
// @Param formID path integer true "表单ID"
// @Success 200 {object} domain.ClubFormStatusFlowDTO
// @Router /api/form/{formID}/status [get]
func getFormStatus(c *gin.Context) {
	formBinding := &cons.FormUriParamBinding{}
	err := c.ShouldBindUri(formBinding)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	flow, err := form_service.FindFormStatusFlow(formBinding.FormID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK, flow)
}
func addNodeToFormStatusFlow(c *gin.Context) {
	panic("not implemented")
}

type upsertFormStatusFlowMutation struct {
	FlowID *int64 `json:"flow_id,omitempty" form:"flow_id"`
}

func updateFormStatusFlowNode(c *gin.Context) {
	panic("not implemented")
}

type upsertFormStatusFlowReq struct {
	upsertFormStatusFlowMutation
	club_service.FormStatusFlowNode
}

// @Summary 更新/上传新的表单状态
// @Description
// @Tags 表单
// @Param formID path integer true "表单ID"
// @Param value body status.upsertFormStatusFlowReq true "v"
// @Router /api/form/{formID}/status [post]
func upsertFormStatusFlow(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithDatabaseError(c, err)
		return
	}

	formBinding := &cons.FormUriParamBinding{}
	if err = c.ShouldBindUri(formBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	form, err := form_service.FindFormById(formBinding.FormID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	if form.ClubID == nil {
		services.AbortWithError(c, errs.ErrFormIsOrphan)
		return
	}
	if owner, err := club_service.CheckIsClubOwner(user.ID, *form.ClubID); err != nil || !owner {
		if err != nil {
			services.AbortWithError(c, err)
			return
		}
		if !owner {
			services.AbortWithError(c, errs.ErrNotClubManager)
		}
	}
	rootNode := &club_service.FormStatusFlowNode{}
	if err = c.ShouldBind(rootNode); err != nil {
		services.AbortWithError(c, err)
		return
	}
	mutation := &upsertFormStatusFlowMutation{}
	if err = c.ShouldBind(mutation); err != nil {
		services.AbortWithError(c, err)
		return
	}
	err = club_service.UpsertFormStatusFlow(&club_service.UpsertFormStatusFlowMutation{
		FlowID:   mutation.FlowID,
		UserID:   user.ID,
		ClubID:   *form.ClubID,
		RootNode: rootNode,
	})
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.AbortWithStatus(http.StatusNoContent)
}

func ConfigureFormStatusController(r *gin.RouterGroup) {
	r.GET("/", getFormStatus)
	r.POST(fmt.Sprintf("/flow/:%s", cons.FormStatusFlowUriParam), auth_middleware.AuthLoginMiddleware(), addNodeToFormStatusFlow)
	r.PUT(fmt.Sprintf("/flow/:%s", cons.FormStatusFlowUriParam), auth_middleware.AuthLoginMiddleware(), updateFormStatusFlowNode)
	r.POST("/", upsertFormStatusFlow)

}
